{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 数据"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 248,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "def load_data(filename):\n",
    "    \"\"\"载入数据。\"\"\"\n",
    "    xys = []\n",
    "    with open(filename, 'r') as f:\n",
    "        for line in f:\n",
    "            xys.append(map(float, line.strip().split()))\n",
    "        xs, ys = zip(*xys)\n",
    "        return np.asarray(xs), np.asarray(ys)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 不同的基函数 (basis function)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 249,
   "metadata": {},
   "outputs": [],
   "source": [
    "def identity_basis(x):\n",
    "    ret = np.expand_dims(x, axis=1)\n",
    "    return ret\n",
    "\n",
    "def multinomial_basis(x, feature_num=10):\n",
    "    x = np.expand_dims(x, axis=1) # shape(N, 1)\n",
    "    feat = [x]\n",
    "    for i in range(2, feature_num+1):\n",
    "        feat.append(x**i)\n",
    "    ret = np.concatenate(feat, axis=1)\n",
    "    return ret\n",
    "\n",
    "def gaussian_basis(x, feature_num=10):\n",
    "    centers = np.linspace(0, 25, feature_num)\n",
    "    width = 1.0 * (centers[1] - centers[0])\n",
    "    x = np.expand_dims(x, axis=1)\n",
    "    x = np.concatenate([x]*feature_num, axis=1)\n",
    "    \n",
    "    out = (x-centers)/width\n",
    "    ret = np.exp(-0.5 * out ** 2)\n",
    "    return ret"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 返回一个训练好的模型"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 250,
   "metadata": {},
   "outputs": [],
   "source": [
    "def main(x_train, y_train):\n",
    "    \"\"\"训练模型，并返回从x到y的映射。\"\"\"\n",
    "    \n",
    "    basis_func = gaussian_basis\n",
    "    phi0 = np.expand_dims(np.ones_like(x_train), axis=1)\n",
    "    phi1 = basis_func(x_train)\n",
    "    phi = np.concatenate([phi0, phi1], axis=1)\n",
    "    w = np.dot(np.linalg.pinv(phi), y_train)\n",
    "\n",
    "    def f(x):\n",
    "        phi0 = np.expand_dims(np.ones_like(x), axis=1)\n",
    "        phi1 = basis_func(x)\n",
    "        phi = np.concatenate([phi0, phi1], axis=1)\n",
    "        y = np.dot(phi, w)\n",
    "        return y\n",
    "        pass\n",
    "\n",
    "    return f"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 评估结果"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 251,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(300,)\n",
      "(200,)\n",
      "训练集预测值与真实值的标准差：0.4\n",
      "预测值与真实值的标准差：0.4\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "def evaluate(ys, ys_pred):\n",
    "    \"\"\"评估模型。\"\"\"\n",
    "    std = np.sqrt(np.mean(np.abs(ys - ys_pred) ** 2))\n",
    "    return std\n",
    "\n",
    "if __name__ == '__main__':\n",
    "    train_file = 'train.txt'\n",
    "    test_file = 'test.txt'\n",
    "    x_train, y_train = load_data(train_file)\n",
    "    x_test, y_test = load_data(test_file)\n",
    "    print(x_train.shape)\n",
    "    print(x_test.shape)\n",
    "\n",
    "    f = main(x_train, y_train)\n",
    "\n",
    "    y_train_pred = f(x_train)\n",
    "    std = evaluate(y_train, y_train_pred)\n",
    "    print('训练集预测值与真实值的标准差：{:.1f}'.format(std))\n",
    "    \n",
    "    y_test_pred = f(x_test)\n",
    "    std = evaluate(y_test, y_test_pred)\n",
    "    print('预测值与真实值的标准差：{:.1f}'.format(std))\n",
    "\n",
    "    plt.plot(x_train, y_train, 'ro', markersize=3)\n",
    "    plt.plot(x_test, y_test_pred, 'k')\n",
    "    plt.xlabel('x')\n",
    "    plt.ylabel('y')\n",
    "    plt.title('Linear Regression')\n",
    "    plt.legend(['train', 'test', 'pred'])\n",
    "    plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
